home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CBASE102.ARJ / CBOPEN.C < prev    next >
Text File  |  1991-09-23  |  5KB  |  214 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "@(#)cbopen.c    1.5 - 91/09/23" */
  5.  
  6. #include <ansi.h>
  7.  
  8. /* ansi headers */
  9. #include <errno.h>
  10. #ifdef AC_STRING
  11. #include <string.h>
  12. #endif
  13.  
  14. /* library headers */
  15. #include <blkio.h>
  16. #include <btree.h>
  17. #include <lseq.h>
  18.  
  19. /* local headers */
  20. #include "cbase_.h"
  21.  
  22. /* cbase control structure table definition */
  23. cbase_t cbb[CBOPEN_MAX];
  24.  
  25. /* cbase record position comparison function */
  26. #ifdef AC_PROTO
  27. int cbrposcmp(const void *p1, const void *p2, size_t n)
  28. #else
  29. int cbrposcmp(p1, p2, n)
  30. const void *p1;
  31. const void *p2;
  32. size_t n;
  33. #endif
  34. {
  35.     cbrpos_t rpos1 = NIL;
  36.     cbrpos_t rpos2 = NIL;
  37.  
  38.     memcpy(&rpos1, p1, sizeof(rpos1));
  39.     memcpy(&rpos2, p2, sizeof(rpos2));
  40.     if (rpos1 < rpos2) {
  41.         return -1;
  42.     } else if (rpos1 > rpos2) {
  43.         return 1;
  44.     }
  45.  
  46.     return 0;
  47. }
  48.  
  49. /* btree field definition list */
  50. static btfield_t btfldv[] = {
  51.     {
  52.         0,
  53.         0,
  54.         NULL,
  55.         BT_FASC,
  56.     },
  57.     {
  58.         0,
  59.         sizeof(cbrpos_t),
  60.         cbrposcmp,
  61.         BT_FASC,
  62.     },
  63. };
  64.  
  65. /*man---------------------------------------------------------------------------
  66. NAME
  67.      cbopen - open a cbase
  68.  
  69. SYNOPSIS
  70.      #include <cbase.h>
  71.  
  72.      cbase_t *cbopen(cbname, type, fldc, fldv)
  73.      const char *cbname;
  74.      char *type;
  75.      int fldc;
  76.      const cbfield_t fldv[];
  77.  
  78. DESCRIPTION
  79.      The cbopen function opens the cbase named by cbname.  A pointer
  80.      to the cbase_t control structure associated with the cbase is
  81.      returned.
  82.  
  83.      type is a character string having one of the following values:
  84.  
  85.           "r"            open for reading
  86.           "r+"           open for update (reading and writing)
  87.  
  88.      See cbcreate for explanation of the field count fldc and the
  89.      field definition list fldv.
  90.  
  91.      cbopen will fail if one or more of the following is true:
  92.  
  93.      [EINVAL]       cbname is the NULL pointer.
  94.      [EINVAL]       type is not "r" or "r+".
  95.      [EINVAL]       fldc is less than 1.
  96.      [EINVAL]       fldv is the NULL pointer.
  97.      [EINVAL]       fldv contains an invalid field definition.
  98.      [CBECORRUPT]   A file in the named cbase is corrupt.
  99.      [CBEMFILE]     Too many open cbases.  The maximum is defined as
  100.                     CBOPEN_MAX in <cbase.h>.
  101.  
  102. SEE ALSO
  103.      cbclose, cbcreate.
  104.  
  105. DIAGNOSTICS
  106.      On failure cbopen returns a NULL pointer, and is errno set to
  107.      indicate the error.
  108.  
  109. NOTES
  110.      The same field count and field definition list with which the
  111.      cbase was created must be used each time the cbase is opened.
  112.      Otherwise the results are undefined.
  113.  
  114. ------------------------------------------------------------------------------*/
  115. #ifdef AC_PROTO
  116. cbase_t *cbopen(const char *cbname, const char *type, int fldc, const cbfield_t fldv[])
  117. #else
  118. cbase_t *cbopen(cbname, type, fldc, fldv)
  119. const char *cbname;
  120. const char *type;
  121. int fldc;
  122. const cbfield_t fldv[];
  123. #endif
  124. {
  125.     int    terrno    = 0;
  126.     cbase_t *cbp    = NULL;
  127.     int    i    = 0;
  128.  
  129.     /* validate arguments */
  130.     if (cbname == NULL || type == NULL || fldc < 1 || fldv == NULL) {
  131.         errno = EINVAL;
  132.         return NULL;
  133.     }
  134.  
  135.     /* find free slot in cbb table */
  136.     for (cbp = cbb; cbp < (cbb + CBOPEN_MAX); ++cbp) {
  137.         if (!(cbp->flags & CBOPEN)) {
  138.             break;        /* found */
  139.         }
  140.     }
  141.     if (cbp >= cbb + CBOPEN_MAX) {
  142.         errno = CBEMFILE;
  143.         return NULL;        /* no free slots */
  144.     }
  145.  
  146.     /* open record file */
  147.     if (strcmp(type, CB_READ) == 0) {
  148.         cbp->flags = CBREAD;
  149.     } else if (strcmp(type, CB_RDWR) == 0) {
  150.         cbp->flags = CBREAD | CBWRITE;
  151.     } else {
  152.         errno = EINVAL;
  153.         return NULL;
  154.     }
  155.     cbp->lsp = lsopen(cbname, type);
  156.     if (cbp->lsp == NULL) {
  157.         if (errno == LSECORRUPT) errno = CBECORRUPT;
  158.         if (errno != ENOENT && errno != CBECORRUPT) CBEPRINT;
  159.         memset(cbp, 0, sizeof(*cbb));
  160.         cbp->flags = 0;
  161.         return NULL;
  162.     }
  163.  
  164.     /* validate arguments */
  165.     if (!cb_fvalid(UINT_MAX, fldc, fldv)) {
  166.         lsclose(cbp->lsp);
  167.         memset(cbp, 0, sizeof(*cbb));
  168.         cbp->flags = 0;
  169.         errno = EINVAL;
  170.         return NULL;
  171.     }
  172.  
  173.     /* copy field definitions into cbase structure */
  174.     cbp->fldc = fldc;
  175.     cbp->fldv = NULL;
  176.     cbp->btpv = NULL;
  177.     if (cb_alloc(cbp) == -1) {
  178.         terrno = errno;
  179.         lsclose(cbp->lsp);
  180.         memset(cbp, 0, sizeof(*cbb));
  181.         cbp->flags = 0;
  182.         errno = terrno;
  183.         return NULL;
  184.     }
  185.     memcpy(cbp->fldv, fldv, cbp->fldc * sizeof(*cbp->fldv));
  186.  
  187.     /* open key files */
  188.     for (i = 0; i < cbp->fldc; ++i) {
  189.         if (cbp->fldv[i].flags & CB_FKEY) {
  190.             btfldv[1].offset = btfldv[0].len = cbp->fldv[i].len;
  191.             btfldv[0].cmp = cbcmpv[cbp->fldv[i].type];
  192.             cbp->btpv[i] = btopen(cbp->fldv[i].filename, type, 2, btfldv);
  193.             if (cbp->btpv[i] == NULL) {
  194.                 if (errno != ENOENT && errno != BTECORRUPT) CBEPRINT;
  195.                 if (errno == BTECORRUPT) errno = CBECORRUPT;
  196.                 terrno = errno;
  197.                 for (i--; i >= 0; i--) {
  198.                     if (cbp->fldv[i].flags & CB_FKEY) {
  199.                         btclose(cbp->btpv[i]);
  200.                     }
  201.                 }
  202.                 lsclose(cbp->lsp);
  203.                 cb_freemem(cbp);
  204.                 memset(cbp, 0, sizeof(*cbb));
  205.                 cbp->flags = 0;
  206.                 errno = terrno;
  207.                 return NULL;
  208.             }
  209.         }
  210.     }
  211.  
  212.     return cbp;
  213. }
  214.